#include "common.h"
#include "console.h"
#include "linecontroller.h"

LineController::LineController(Console *console): Controller(console)
{
	cmd = new char[COLS];
	length = 0;
}

LineController::~LineController()
{
	delete cmd;
}

bool LineController::processMessage(chtype message)
{
	WINDOW *status = this->activeConsole->getStatusbar()->getBar();
	bool helpFlag = false;
	WINDOW *help;
	
	if (message == keyesc)
	{
		if (helpFlag)
			delwin(help);
		else
		{
			length = 0;
			this->activeConsole->setController(this->activeConsole->getCommandController());
			this->activeConsole->update();
		}
	}
	else if (message == 263)
	{
		length--;
		wmove(status, 0, length);
		wdelch(status);
		if (length == 0)
		{
			this->activeConsole->setController(this->activeConsole->getInsertController());
			this->activeConsole->update();
		}
	}
	else if(message == keyenter)
	{
		cmd[length] = '\0';
		
		if (strcmp(cmd, ":help") == 0)
		{
			//a little widget
			helpFlag = true;
			help = subwin(this->activeConsole->getWindow(), LINES, COLS, 0, 0);	
		}	
		else if (strcmp(cmd, ":q!") == 0)
		{
			this->activeConsole->postQuite();
		}
		else if (strcmp(cmd, ":qw") == 0 || strcmp(cmd, ":wq") == 0)
		{
			//save and exit cppvi
			CppVi::getInstance()->getDocument()->saveFile(NULL);
			this->activeConsole->postQuite();
		}
		else if (strcmp(cmd, ":w") == 0)
		{
			//save
			if (!CppVi::getInstance()->getDocument()->saveFile(NULL))
			{
				wclear(status);
				wattron(status, A_REVERSE);
				wprintw(status, "Please enter the filename");
				wattroff(status, A_REVERSE);
				this->activeConsole->getStatusbar()->update(0, 0);
				sleep(1);
			}
			length = 0;
			this->activeConsole->update();
			this->activeConsole->setController(this->activeConsole->getCommandController());
		}
		else if (strncmp(cmd, ":w ", 3) == 0)
		{
			if (strrchr(cmd + 3, ' ') != NULL)
			{
				wclear(status);
				wattron(status, A_REVERSE);
				wprintw(status, "Not an editor command");
				wattroff(status, A_REVERSE);
				this->activeConsole->getStatusbar()->update(0, 0);
				sleep(1);
			}
			else
			{
				//save as
				CppVi::getInstance()->getDocument()->saveFile(cmd + 3);
			}
			length = 0;
			this->activeConsole->update();
			this->activeConsole->setController(this->activeConsole->getCommandController());
		}
		else if (strncmp(cmd, ":find ", 6) == 0)
		{
			if (!CppVi::getInstance()->getDocument()->find(cmd + 6))
			{
				wclear(status);
				wattron(status, A_REVERSE);
				wprintw(status, "String Not Found");
				wattroff(status, A_REVERSE);
				this->activeConsole->getStatusbar()->update(0, 0);
				sleep(1);
			}
			length = 0;
			this->activeConsole->update();
			this->activeConsole->setController(this->activeConsole->getCommandController());
		}
		else if (strncmp(cmd, ":replace ", 9) == 0)
		{
			char word1[32];
			char word2[32];
			int len1 = index(cmd + 9);
			strncpy(word1, cmd + 9, len1);
			word1[len1] = '\0';
			int len2 = index(cmd + 9 + len1 + 1);
			strncpy(word2, cmd + 9 + len1 + 1, len2);
			word2[len2] = '\0';
			
			if (!CppVi::getInstance()->getDocument()->replace(word1, word2))
			{
				wclear(status);
				wattron(status, A_REVERSE);
				wprintw(status, "String Not Found");
				wattroff(status, A_REVERSE);
				this->activeConsole->getStatusbar()->update(0, 0);
				sleep(1);
			}
			length = 0;
			this->activeConsole->update();
			this->activeConsole->setController(this->activeConsole->getCommandController());
		}
		else if (strncmp(cmd, ":open ", 6) == 0)
		{
			if (!CppVi::getInstance()->getDocument()->loadFile(cmd + 6))
			{
				wclear(status);
				wattron(status, A_REVERSE);
				wprintw(status, "File Not Found");
				wattroff(status, A_REVERSE);
				this->activeConsole->getStatusbar()->update(0, 0);
				sleep(1);
			}
			length = 0;
			this->activeConsole->update();
			this->activeConsole->setController(this->activeConsole->getCommandController());
		}
		else
		{
			wclear(status);
			wattron(status, A_REVERSE);
			wprintw(status, "Not an editor command");
			wattroff(status, A_REVERSE);
			length = 0;
			this->activeConsole->getStatusbar()->update(0, 0);
			sleep(1);
			this->activeConsole->setController(this->activeConsole->getCommandController());
		}
		this->activeConsole->update();
		return true;
	}
	else
	{
		cmd[length] = message;
		length++;
		waddch(status, message);
		//printw("%d", message);
	}
	this->activeConsole->getStatusbar()->update(0, 0);
	return true;
}

int LineController::getMode() const
{
	return lineMode;
}

int LineController::index(const char *text)
{
	int length = strlen(text);
	int i = 0;
	for ( ; i < length; i++)
	{
		if (text[i] == ' ')
			break;
	}
	return i;
}
